//-------------------------------------------------------------------
//	Copyright (c) 2010-2012 Zhirnov Andrey
//	This file is part of the "UXGEN" project.
//	See copyright notice in "Engine.h".
//-------------------------------------------------------------------

#ifndef _UX_RTPASS_CUSTOM_H
#define _UX_RTPASS_CUSTOM_H

#include "IRTPass.h"
#include "TRTMessage.h"
#include "../ConfiguredRTTypes.h"
#include "../../../../Resources/PostProcess/IPostProcess.h"

namespace Engine
{
namespace RenderUtils
{

	//
	// Bind Textures Pass
	//

	class CRTBindTexturesPass : public IRTPass
	{
	protected:
		pptex_array_t	_aTextures;
		
	protected:
		static void _s_Process(void *);

	public:
		CRTBindTexturesPass(IRTPass *pParent);
		~CRTBindTexturesPass();

		bool Create(const pptex_array_t &aTextures);

		virtual bool ProcessMessage(TRTMessage &sMsg);

		virtual EPassType GetPassType() const		{ return BIND_TEXTURES; }
	};



	//
	// Set Render Targets Pass
	//

	class CRTSetRenderTargetsPass : public IRTPass
	{
	public:
		struct TRenderTarget
		{
			CTexturePtr			pTexture;
			e_fbo_attach::type	eAttach;
			uint				uLayer;
			uint				uLOD;
			///
			TRenderTarget(): eAttach(e_fbo_attach::COLOR_0), uLayer(0), uLOD(0) {}
			TRenderTarget(const CTexturePtr tex, e_fbo_attach::type attach, uint layer, uint lod):
				pTexture(tex), eAttach(attach), uLayer(layer), uLOD(lod) {}
		};
		typedef array< TRenderTarget >	render_target_array_t;

	protected:
		FBO_t				*	_pFBO;
		render_target_array_t	_aTargets;
		
	protected:
		static void _s_SetTargets(void *);
		static void _s_ResetTargets(void *);

	public:
		CRTSetRenderTargetsPass(IRTPass *pParent);
		~CRTSetRenderTargetsPass();

		bool Create(const render_target_array_t &aRTs);

		virtual bool ProcessMessage(TRTMessage &sMsg);

		virtual EPassType GetPassType() const		{ return SET_RENDER_TARGET; }
	};



	//
	// Cycle Pass
	//

	class CRTCyclePass : public IRTPass
	{
	protected:
		IRTPass	*	_pPass;
		ivec4		_vIteration;
		
	protected:
		static void _s_Process(void *);
		static void _s_ProcessRev(void *);

	public:
		CRTCyclePass(IRTPass *pParent);
		~CRTCyclePass();

		bool Create(const ivec3 &vIter, IRTPass *pPass);
		
		virtual bool ProcessMessage(TRTMessage &sMsg);

		virtual EPassType GetPassType() const		{ return CYCLE; }
	};



	//
	// Custom Pass
	//

	class CRTCustomPass : public IRTPass
	{
	protected:
		typedef pod_array< IRTPass *>	rt_pass_array_t;
		
	protected:
		rt_pass_array_t		_aPasses;
		
	protected:
		static void _s_Process(void *);

	public:
		CRTCustomPass(IRTPass *pParent);
		~CRTCustomPass();

		bool Create(const rt_pass_array_t &aPasses);
		
		virtual bool ProcessMessage(TRTMessage &sMsg);

		virtual EPassType GetPassType() const		{ return CUSTOM; }
	};



	//
	// Branch Pass
	//

	class CRTBranchPass : public IRTPass
	{
	protected:
		IRTPass		*	_pThenPass,
					*	_pElsePass;
		bool		*	_pBoolVal;
		
	protected:
		static void _s_Process(void *);

	public:
		CRTBranchPass(IRTPass *pParent);
		~CRTBranchPass();

		bool Create(const string &sName, IRTPass *pThen, IRTPass *pElse);
		
		virtual bool ProcessMessage(TRTMessage &sMsg);

		virtual EPassType GetPassType() const		{ return BRANCH; }
	};



	//
	// PostProcess Pass
	//

	class CRTPostProcessPass : public IRTPass
	{
	public:
		typedef CRTSetRenderTargetsPass::TRenderTarget				TRenderTarget;
		typedef CRTSetRenderTargetsPass::render_target_array_t		render_target_array_t;
		
	protected:
		FBO_t			*		_pFBO;
		IPostProcessPtr			_pPostProcess;
		render_target_array_t	_aTargets;
		
	protected:
		static void _s_Process(void *);

	public:
		CRTPostProcessPass(IRTPass *pParent);
		~CRTPostProcessPass();

		bool Create(const IPostProcessBasePtr &, const pptex_array_t &, const render_target_array_t &);
		
		virtual bool ProcessMessage(TRTMessage &sMsg);

		virtual EPassType GetPassType() const		{ return POSTPROCESS; }
	};



	//
	// Set GLStates Pass
	//

	class CRTSetGLStatesPass : public IRTPass
	{
	public:
		typedef array< TGLState >	glstate_array_t;

	protected:
		TGLRenderState				_sState;
		glstate_array_t				_aStates;
		e_render_state_lock::type	_eRSLock;
		
	protected:
		static void _s_Process(void *);

	public:
		CRTSetGLStatesPass(IRTPass *pParent);
		~CRTSetGLStatesPass();
		
		bool Create(const glstate_array_t &aStates, const TGLRenderState &sState,
					e_render_state_lock::type eRSLock);

		virtual bool ProcessMessage(TRTMessage &sMsg);

		virtual EPassType GetPassType() const		{ return SET_GL_STATE; }
	};



	//
	// Swizzle Pass
	//

	class CRTSwizzlePass : public IRTPass
	{
	public:
		struct TCase
		{
			IRTPass	*	pPass;
			uint		uValue;
			///
			TCase(): pPass(nullptr), uValue(0) {}
			TCase(IRTPass *pass, uint val): pPass(pass), uValue(val) {}
		};

		typedef array< TCase >	case_array_t;

	protected:
		IRTPass		*		_pDefault;
		case_array_t		_aCase;
		uint		*		_pValue;
		
	protected:
		static void _s_Process(void *);

	public:
		CRTSwizzlePass(IRTPass *pParent);
		~CRTSwizzlePass();

		bool Create(const string &sValue, const case_array_t &aCase, IRTPass *pDefault);
		
		virtual bool ProcessMessage(TRTMessage &sMsg);

		virtual EPassType GetPassType() const		{ return SWIZZLE; }
	};

//-------------------------------------------------------------------

}	// RenderUtils
}	// Engine

#endif	// _UX_RTPASS_CUSTOM_H